home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
PopupItem.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
7KB
|
311 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "PopupItem.h"
#include "Class.h"
#include "Menu.h"
#include "SeqColl.h"
#include "Look.h"
#include "MenuBar.h"
#include "TextItem.h"
#include "WindowSystem.h"
#include "Clipper.h"
#include "Filler.h"
const int cPullRight= 16;
//---- MenuButton --------------------------------------------------------------
NewMetaImpl(MenuButton,StateButton, (TP(menu)));
MenuButton::MenuButton(int id, Menu *m) : StateButton(id)
{
menu= m;
state= cIdNone;
SetFlag(eVObjVFixed|eVObjHFixed);
}
MenuButton::~MenuButton()
{
SafeDelete(menu);
}
Menu *MenuButton::MyMenu()
{
return menu;
}
OStream& MenuButton::PrintOn(OStream &s)
{
StateButton::PrintOn(s);
return s << menu SP;
}
IStream& MenuButton::ReadFrom(IStream &s)
{
StateButton::ReadFrom(s);
return s >> menu;
}
void MenuButton::CollectParts(Collection* col)
{
StateButton::CollectParts(col);
if (menu)
col->Add(menu);
}
void MenuButton::SetCollection(SeqCollection *col, bool freeold)
{
if (menu)
menu->SetCollection(col, freeold);
}
//---- PopupButton -------------------------------------------------------------
NewMetaImpl0(PopupButton,MenuButton);
PopupButton::PopupButton(int id, int dfltid, Menu *m) : MenuButton(id, m)
{
SetValue(dfltid, FALSE);
ResetFlag(eVObjHFixed);
}
void PopupButton::SetContainer(VObject *v)
{
MenuButton::SetContainer(v);
menu->SetNextHandler(this);
}
void PopupButton::Control(int id, int part, void *v)
{
if (id == cIdNone)
return;
if (part == cPartViewSize || part == cPartAnyChange)
return;
MenuButton::Control(id, part, v);
}
Command *PopupButton::DispatchEvents(Point lp, Token &t, Clipper *vf)
{
if (t.Code == eEvtLeftButton && !(t.Flags & eFlgButDown)) {
Command *currCmd= DoLeftButtonDownCommand(lp, t, WindowSystem::Clicks);
if (currCmd && currCmd != gNoChanges && vf)
currCmd= vf->TrackInContent(lp, t, currCmd);
return currCmd;
}
return MenuButton::DispatchEvents(lp, t, vf);
}
Metric PopupButton::GetMinSize()
{
if (menu) {
Metric m;
Iter next(menu->GetCollection());
register VObject *vop;
while (vop= (VObject*) next())
m.Merge(vop->GetMinSize());
return m.Expand(2);
}
return MenuButton::GetMinSize();
}
void PopupButton::DoTrackMouse(TrackPhase atp, Point)
{
if (Enabled() && atp == eTrackPress && menu) {
int id= menu->Popup(GetOrigin()+Point(0,-1), this, state, TRUE, TRUE, gRect0);
if (id != cIdNone) {
SetValue(id);
Control(GetId(), cPartToggle, (void*)id);
}
}
}
void PopupButton::Draw(Rectangle r)
{
VObject *v= menu->FindItem(state);
if (v == 0)
v= (VObject*)menu->GetCollection()->At(0);
if (v) {
int oldstate;
StateButton *stb= 0;
if (v->IsKindOf(StateButton))
stb= (StateButton*) v;
if (stb) {
oldstate= stb->GetValue();
stb->SetValue(0, FALSE);
}
state= v->GetId();
Point old(v->GetOrigin());
bool isopen= v->IsOpen();
if (!isopen)
v->Open();
v->SetOrigin(GetOrigin()+gPoint2);
v->SetExtent(GetExtent()-gPoint4);
v->DrawAll(r);
gLook->PopupButtonLayout()->Adorn(this, r, Enabled() ? 0 : 2);
v->SetOrigin(old);
if (!isopen)
v->Close();
if (stb)
stb->SetValue(oldstate, FALSE);
}
}
//---- PullDownButton ----------------------------------------------------------
NewMetaImpl0(PullDownButton,MenuButton);
PullDownButton::PullDownButton(Menu *m) : MenuButton(cIdNone, m)
{
if (m)
Add(new TextItem(m->GetName(), gSysFont, Point(8,2)));
}
PullDownButton::PullDownButton(int id, Menu *m) : MenuButton(id, m)
{
if (m)
Add(new TextItem(m->GetName(), gSysFont, Point(8,2)));
}
extern bool gInButtonFlush;
void PullDownButton::DoTrackMouse(TrackPhase atp, Point)
{
if (Enabled()) {
switch (atp) {
case eTrackPress:
Highlight(On);
state= cIdNone;
if (!gInButtonFlush && menu && Enabled()) {
state= menu->Popup(contentRect.SW(), this, cIdNone,
FALSE, TRUE,
Rectangle(Point(0, -contentRect.extent.y), contentRect.extent));
Highlight(Off);
}
break;
case eTrackRelease:
if (state >= 0) {
if (gFirstHandler) {
EvtHandler *old= gFirstHandler;
Command *cmd= gFirstHandler->DoMenuCommand(state);
gFirstHandler= old;
gFirstHandler->PerformCommand(cmd);
} else
PerformCommand(DoMenuCommand(state));
UpdateEvent();
}
Highlight(Off);
break;
case eTrackExit:
Highlight(Off);
break;
default:
break;
}
}
}
void PullDownButton::DrawHighlight(Rectangle r)
{
VObject::DrawHighlight(r);
}
/*
void PullDownButton::InputKbd(Token &t)
{
if (Enabled() && Size() > 1) {
TextItem *ti= (TextItem*) At(1);
char *s= ti->AsString();
if (s && *s && upcase[s[1]] == upcase[t.Code & 0x7f])
Control(GetId(), cPartToggle, (void*) 1);
}
}
int MenuBar::CheckKey(Token &t)
{
int cmd= cIdNone;
Iter next(mb->MakeIterator());
register VObject *vop;
while (vop= (VObject*) next()) {
if (vop->IsKindOf(PullDownButton)) {
PullDownButton *pdb= (PullDownButton*) vop;
cmd= pdb->Menu()->CheckKey(t);
if (cmd != cIdNone) {
pdb->Flush();
return cmd;
}
}
}
return cIdNone;
}
*/
//---- MenuItem ----------------------------------------------------------------
NewMetaImpl(MenuItem,MenuButton, (T(lastxpos), T(enterxpos)));
MenuItem::MenuItem(int id, VObject *v, Menu *m) : MenuButton(id, m)
{
Add(v);
}
Metric MenuItem::GetMinSize()
{
return gLook->MenuItemLayout()->GetMinSize(this);
}
void MenuItem::DrawInner(Rectangle, bool highlight)
{
int code= 0;
SETBIT(code, 4);
if (highlight)
SETBIT(code, 3);
if (Enabled())
SETBIT(code, 5);
gLook->MenuItemLayout()->Adorn(this, contentRect, code);
}
void MenuItem::SetOrigin(Point at)
{
VObject::SetOrigin(at);
gLook->MenuItemLayout()->SetOrigin(this, at);
}
void MenuItem::DoTrackMouse(TrackPhase atp, Point p)
{
if (Enabled() && menu) {
switch (atp) {
case eTrackPress:
Highlight(On);
enterxpos= lastxpos= p.x;
state= -1;
break;
case eTrackMove:
case eTrackIdle:
if (p.x > lastxpos &&
(p.x > enterxpos+cPullRight || p.x > At(0)->contentRect.E().x)) {
p.y= contentRect.W().y-2;
state= menu->Pulldown(p, this);
lastxpos= contentRect.SE().x+1;
} else
lastxpos= p.x;
break;
case eTrackRelease:
case eTrackExit:
if (state != cIdNone)
Control(state, cPartToggle, (void*)0);
Highlight(Off);
default:
lastxpos= contentRect.SE().x+1;
enterxpos= p.x;
break;
}
}
}